Nextflow 入門 Hello World ワークフローの実行内容を解説
Nextflow に入門しました。Workflow の独自言語でワークフローを定義することになるわけですが、初見で自由に書けるほど甘くはなく相応の学習コストが必要でした。そこで定番の Helo World を例に基本的な説明と、書き方の参考になったドキュメントを紹介します。
実行環境
Name | Version |
---|---|
Nextflow | 23.04.1 |
DSL | 2 |
DSL のバージョンに注意
Nextflow 独自のワークフロー記述言語(Domain Specific Language)には2バージョンあります。旧世代のDSL
と現行世代のDSL2
です。
DSL
のバージョン違いで注意しないといけないのは完全な後方互換性はないことです。
Nextflow の書き方を学ぶために検索すると旧世代のDSL
で記述されたワークフローがヒットすることもあります。そのまま実行するには「旧世代のDSL
を使ったワークフローですと明示」しないと現行の Nextflow のバージョンだと実行できません。
DSL
からDSL2
への移行ガイドはあるのですが Nextflow の記述方法がわからない段階では難易度が高く感じます。私は Nextflow の記述方法がわかってない状態で書き換えは無理だなと諦めました。
DSL 2 — Nextflow 23.04.1 documentation
参考になったドキュメント類
これから紹介するmain.nf
の内容を理解するためには Nextflow の Basic Training で説明されている内容が有用でした。
最初に公式ドキュメントを参考にされるなら上記リンクがよろしいかと思います。
Hello World を紐解く
Nextflow のセットアップをした後は動作確認のためにnextflow run hello
コマンドを一度は実行した経験があるのではないでしょうか?
$ nextflow run hello N E X T F L O W ~ version 23.04.1 Launching `https://github.com/nextflow-io/hello` [serene_yalow] DSL2 - revision: 1d71f857bb [master] executor > local (4) [b0/6ca63b] process > sayHello (1) [100%] 4 of 4 ✔ Hola world! Hello world! Ciao world! Bonjour world!
nextflow run
を実行するとこの場合はhello
というファイル名のファイルをカレントディレクトリから探し、なければ同じ名前の GitHub のリポジトリを探し、実行スクリプトを取得してきてローカルで実行した結果が表示されたことになります。
When you launch a script execution with Nextflow, it will look for a file with the pipeline name you’ve specified. If that file does not exist, it will look for a public repository with the same name on GitHub (unless otherwise specified). If it is found, the repository is automatically downloaded to your computer and executed. Pipeline sharing — Nextflow 23.04.1 documentation
つまり、今回はこちらのnextflow-io/helloリポジトリからmain.nf
ファイルを取得し実行していたわけです。
#!/usr/bin/env nextflow nextflow.enable.dsl=2 process sayHello { input: val x output: stdout script: """ echo '$x world!' """ } workflow { Channel.of('Bonjour', 'Ciao', 'Hello', 'Hola') | sayHello | view }
Hello World のスクリプト(main.nf
)の内容を解説します。
main.nf はなにをしているのか?
わかりやすくコメントを追記しました。気になって調べた点は別途後述しています。
#!/usr/bin/env nextflow // シェバンで nextflow を指定 nextflow.enable.dsl=2 // DSL2 を利用すると明示的に宣言 process sayHello { // プロセスはいわゆる関数みたいなもの input: val x // Channel.of() の引数で渡している文字列(Bonjor)を変数 x に格納 output: stdout // 出力先を標準出力に指定 ※標準出力へ内容を返すにはオペレーターの view が必要 script: """ echo '$x world!' // $変数名で変数を展開 """ } workflow { // プロセスの実行順番やプロセスへ渡す引数など全体の処理の流れを定義 Channel.of('Bonjour', 'Ciao', 'Hello', 'Hola') | sayHello | view // 後述 }
DSL2 の利用を明示について
Nextflow 23.04.1 ではデフォルトで DSL2 が利用されます。そのため、現行バージョンで実行する分にはnextflow.enable.dsl=2
の記述を省略しても動作します。
DSL 2 — Nextflow 23.04.1 documentation
プロセス名の命名規則について
プロセス名はsayHello
とキャメルケース(ローワーキャメルケース)で書かれていますが、Nextflow ではすべて大文字で書くアッパケースが一般的とドキュメントに記述がありました。
The process name is commonly written in upper case by convention. Processes - training.nextflow.io
workflow 内の指示について
workflow で記述した process の実行順番の指示や、引数を渡したり全体の流れの指示を行います。
指示内容がワンライナー(実行コマンドをパイプで繋いで1行にまとめてある)のため逆に理解に苦しみました。
workflow { Channel.of('Bonjour', 'Ciao', 'Hello', 'Hola') | sayHello | view }
理解しづらかったのでパイプを分解して同じ動作する様に書き換えたものが以下です。
workflow { input_ch = Channel.of('Bonjour', 'Ciao', 'Hello', 'Hola') results = sayHello(input_ch) results.view() }
Channel.of()
の動作は与えられた引数に対応する引数毎の個別のチャネルが生成されます。Channel
にはof
メソッドがあり、その説明が以下です。
The of method allows you to create a channel that emits the arguments provided to it, for example: Channels — Nextflow 23.04.1 documentation
つまり、引数毎のキューが生成され、個別のキュー内にはそれぞれメッセージとして引数の値が入っています。その状態をinput_ch
に格納しています。
次にsayHello
プロセスにinput_ch
を引数にして渡します。チャンネル毎に並列でsayHello
が実行されます。sayHello
プロセスは引数に指定したBonjor
を変数x
に格納しecho
コマンドで変数の内容を展開して実行しています。その出力結果は標準出力(stdout
)を指定しています。実行結果を workflow の定義内でresults
に格納しています。
process sayHello { input: val x output: stdout script: """ echo '$x world!' """ }
そして、view がないと標準出力へ結果を返せないです。
最後にresults.view()
でsayHello
の実行結果を表示しています。これでコンソール画面に文字列が表示されることになります。
view
というオペレーターの存在を知らずstdout
を指定しているのにもかかわらず画面に表示されなくハマりました。
The view operator prints the items emitted by a channel to the console standard output, appending a new line character to each item. For example: Operators - training.nextflow.io
Hello World の実行内容の解説は以上です。
おわりに
RNA-Seq解析パイプラインを作成したかったので[nf-core/rnaseq: RNA sequencing analysis pipeline using STAR, RSEM, HISAT2 or Salmon with gene/isoform counts and extensive quality control.]をベースにして学ぼうかと思ったのですがあまりにも重厚なワークフローで記述方法がわかって初学者が読み解くのは難しかったです。基本的な Nextflow のお作法を学んで最小限のワークフローをゼロから生み出す方法でやっていく方法としました。手始めに Hello World のワークフローの実行内容を調べたときのまとめでした。